#!/usr/bin/env bash

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific

#JAVA_HOME=/usr/jdk64/jdk1.7.0_45
PIDFILE=/var/run/ambari-metrics-collector/ambari-metrics-collector.pid
OUTFILE=/var/log/ambari-metrics-collector/ambari-metrics-collector.out

HBASE_ZK_PID=/var/run/ams-hbase/hbase-${USER}-zookeeper.pid
HBASE_MASTER_PID=/var/run/ams-hbase/hbase-${USER}-master.pid
HBASE_RS_PID=/var/run/ams-hbase/hbase-${USER}-regionserver.pid

HBASE_DIR=/usr/lib/ams-hbase

DAEMON_NAME=timelineserver

COLLECTOR_CONF_DIR=/etc/ambari-metrics-collector/conf
HBASE_CONF_DIR=/etc/ams-hbase/conf

METRIC_COLLECTOR=ambari-metrics-collector

AMS_LOG_DIR=/var/log/ambari-metrics-collector

STOP_TIMEOUT=5

DISTRIBUTED_HBASE=false

function hbase_daemon
{
    local daemon=$1
    local cmd=$2
    local pid

    case "${daemon}" in
      "master")
        pid=${HBASE_MASTER_PID}
      ;;
      "zookeeper")
        pid=${HBASE_ZK_PID}
      ;;
      "regionserver")
        pid=${HBASE_RS_PID}
      ;;
    esac

    daemon_status "${pid}"
    if [[ $? == 0  ]]; then
        echo "${daemon} is running as process $(cat "${pid}"). Continuing"
      else
        # stale pid file, so just remove it and continue on
        rm -f "${pid}" >/dev/null 2>&1
    fi

    ${HBASE_DIR}/bin/hbase-daemon.sh --config ${HBASE_CONF_DIR} ${cmd} ${daemon}



}

function write_pidfile
{
    local pidfile="$1"
    echo $! > "${pidfile}" 2>/dev/null
    if [[ $? -gt 0 ]]; then
      echo "ERROR:  Cannot write pid ${pidfile}."
      exit 1;
    fi
}

function hadoop_java_setup
{
  # Bail if we did not detect it
  if [[ -z "${JAVA_HOME}" ]]; then
    echo "ERROR: JAVA_HOME is not set and could not be found."
    exit 1
  fi

  if [[ ! -d "${JAVA_HOME}" ]]; then
    echo "ERROR: JAVA_HOME ${JAVA_HOME} does not exist."
    exit 1
  fi

  JAVA="${JAVA_HOME}/bin/java"

  if [[ ! -x "$JAVA" ]]; then
    echo "ERROR: $JAVA is not executable."
    exit 1
  fi
  # shellcheck disable=SC2034
  JAVA_HEAP_MAX=-Xmx1g
  HADOOP_HEAPSIZE=${HADOOP_HEAPSIZE:-1024}

  # check envvars which might override default args
  if [[ -n "$HADOOP_HEAPSIZE" ]]; then
    # shellcheck disable=SC2034
    JAVA_HEAP_MAX="-Xmx${HADOOP_HEAPSIZE}m"
  fi
}

function daemon_status()
{
  #
  # LSB 4.1.0 compatible status command (1)
  #
  # 0 = program is running
  # 1 = dead, but still a pid (2)
  # 2 = (not used by us)
  # 3 = not running
  #
  # 1 - this is not an endorsement of the LSB
  #
  # 2 - technically, the specification says /var/run/pid, so
  #     we should never return this value, but we're giving
  #     them the benefit of a doubt and returning 1 even if
  #     our pid is not in in /var/run .
  #

  local pidfile="$1"
  shift

  local pid

  if [[ -f "${pidfile}" ]]; then
    pid=$(cat "${pidfile}")
    if ps -p "${pid}" > /dev/null 2>&1; then
      return 0
    fi
    return 1
  fi
  return 3
}

function start()
{
  hadoop_java_setup


  # hbase_daemon "zookeeper" "start"
  #	hbase_daemon "master" "start"
  #	hbase_daemon "regionserver" "start"
  if [ !"${DISTRIBUTED_HBASE}" ]; then
    echo "Starting HBase."
    hbase_daemon "master" "start"
  else
    echo "Launching in distributed mode. Assuming Hbase daemons up and running."
  fi

	CLASS='org.apache.hadoop.yarn.server.applicationhistoryservice.ApplicationHistoryServer'
	# YARN_OPTS="${YARN_OPTS} ${YARN_TIMELINESERVER_OPTS}"
	# if [[ -n "${YARN_TIMELINESERVER_HEAPSIZE}" ]]; then
	#   JAVA_HEAP_MAX="-Xmx${YARN_TIMELINESERVER_HEAPSIZE}m"
	# fi

	# check if this is needed?
	# export PHOENIX_JAR_PATH=/usr/lib/ambari-metrics/timelineservice/phoenix-client.jar
	# export HBASE_CONF_DIR=${HBASE_DIR}/conf

  daemon_status "${PIDFILE}"
  if [[ $? == 0  ]]; then
    echo "AMS is running as process $(cat "${PIDFILE}"). Exiting"
    exit 0
  else
    # stale pid file, so just remove it and continue on
    rm -f "${PIDFILE}" >/dev/null 2>&1
  fi

  nohup "${JAVA}" "-cp" "/usr/lib/ambari-metrics-collector/*:${COLLECTOR_CONF_DIR}" "${AMS_COLLECTOR_OPTS}" "-Djava.net.preferIPv4Stack=true" "-Dams.log.dir=${AMS_COLLECTOR_LOG_DIR}" "-Dproc_${DAEMON_NAME}" "${CLASS}" "$@" > $OUTFILE 2>&1 &
  PID=$!
  write_pidfile "${PIDFILE}"
  sleep 2

  echo "Verifying ${METRIC_COLLECTOR} process status..."
  if [ -z "`ps ax -o pid | grep ${PID}`" ]; then
    if [ -s ${OUTFILE} ]; then
      echo "ERROR: ${METRIC_COLLECTOR} start failed. For more details, see ${OUTFILE}:"
      echo "===================="
      tail -n 10 ${OUTFILE}
      echo "===================="
    else
      echo "ERROR: ${METRIC_COLLECTOR} start failed"
      rm -f ${PIDFILE}
    fi
    echo "Collector out at: ${OUTFILE}"
    exit -1
  fi

  echo "Collector successfully started."
}

function stop()
{
  pidfile=${PIDFILE}

  if [[ -f "${pidfile}" ]]; then
    pid=$(cat "$pidfile")

    kill "${pid}" >/dev/null 2>&1
    sleep "${STOP_TIMEOUT}"

    if kill -0 "${pid}" > /dev/null 2>&1; then
      echo "WARNING: ${METRIC_COLLECTOR} did not stop gracefully after ${STOP_TIMEOUT} seconds: Trying to kill with kill -9"
      kill -9 "${pid}" >/dev/null 2>&1
    fi

    if ps -p "${pid}" > /dev/null 2>&1; then
      echo "ERROR: Unable to kill ${pid}"
    else
      rm -f "${pidfile}" >/dev/null 2>&1
    fi
  fi

  #stop hbase daemons
  if [ !"${DISTRIBUTED_HBASE}" ]; then
    echo "Stopping HBase master"
    hbase_daemon "master" "stop"
  fi
}

while [[ -z "${_ams_configs_done}" ]]; do
  case $1 in
    --config)
      shift
      confdir=$1
      shift
      if [[ -d "${confdir}" ]]; then
        COLLECTOR_CONF_DIR="${confdir}"
      elif [[ -z "${confdir}" ]]; then
        echo "ERROR: No parameter provided for --config "
        exit 1
      else
        echo "ERROR: Cannot find configuration directory \"${confdir}\""
        exit 1
      fi
    ;;
    --distributed)
      DISTRIBUTED_HBASE=true
      shift
    ;;
    *)
      _ams_configs_done=true
    ;;
  esac
done

# execute ams-env.sh
if [[ -f "${COLLECTOR_CONF_DIR}/ams-env.sh" ]]; then
  . "${COLLECTOR_CONF_DIR}/ams-env.sh"
else
  echo "ERROR: Cannot execute ${COLLECTOR_CONF_DIR}/ams-env.sh." 2>&1
  exit 1
fi

# set pid dir path
if [[ -n "${AMS_COLLECTOR_PID_DIR}" ]]; then
  PIDFILE=${AMS_COLLECTOR_PID_DIR}/ambari-metrics-collector.pid
fi

if [[ -n "${AMS_HBASE_PID_DIR}" ]]; then
  HBASE_ZK_PID=${AMS_HBASE_PID_DIR}/hbase-${USER}-zookeeper.pid
  HBASE_MASTER_PID=${AMS_HBASE_PID_DIR}/hbase-${USER}-master.pid
  HBASE_RS_PID=${AMS_HBASE_PID_DIR}/hbase-${USER}-regionserver.pid
fi

# set out file path
if [[ -n "${AMS_COLLECTOR_LOG_DIR}" ]]; then
  OUTFILE=${AMS_COLLECTOR_LOG_DIR}/ambari-metrics-collector.out
fi

#TODO manage 3 hbase daemons for start/stop/status
case "$1" in

	start)
    daemon_status "${HBASE_MASTER_PID}"
    HBASE_DAEMON_STATUS=$?
    daemon_status "${PIDFILE}"
    DAEMON_STATUS=$?

    if [[ !"${DISTRIBUTED_HBASE}"  && ( ${DAEMON_STATUS} != 0 || ${HBASE_DAEMON_STATUS} != 0 ) ]]; then
      stop
    fi
    start

  ;;
	stop)
    stop

    ;;
	status)
	    daemon_status "${PIDFILE}"
	    if [[ $? == 0  ]]; then
            echo "AMS is running as process $(cat "${PIDFILE}")."
        else
            echo "AMS is not running."
        fi
        #print embedded hbase daemons statuses?
    ;;
	restart)
	  stop
	  start
	;;

esac



